<?php


namespace app\index\model;


use app\index\common\Common;
use think\Db;
use think\Model;

class OrderItem extends Model
{

    public static function getOrderItemsById($id){
        $OrderItemClass=new self();
        $item=$OrderItemClass
            ->where('order_id',$id)
            ->where('del_flag',0)
            ->field('id,order_id,show_index,pro_id,cn_name,en_name,amount,type,gift,selling_price,create_user,create_group,demand_stock,lock_quantity,lock_status,remark')
            ->order('show_index')
            ->select()->toArray();
        return $item;
    }

    public static function getOrderItemsByIds($ids){
        $OrderItemClass=new self();
        $item=$OrderItemClass
            ->where('order_id','in',$ids)
            ->where('del_flag',0)
            ->field('id,order_id,show_index,pro_id,cn_name,en_name,amount,type,selling_price')
            ->select()->toArray();
        return $item;
    }

    public static function getOrderItemsByInvoice($id):array{
        $OrderClass=new Order();
        ['search_user'=>$search_user,'group'=>$group]=ActionRole::checkUserActionRole('product');
        if(!empty($group)){
            $where['create_group']=['=',$group];
        }

        if(!empty($search_user)) {
            $where['create_user'] = ['in', $search_user];
        }
        $where['del_flag']=['=','0'];
        $order_id=$OrderClass->where($where)->where(function ($query)use($id){
            $query->where('order_id','=',$id)->whereOr('receipt_number','=',$id);
        })->value('id');
        if(!$order_id){
            return ['status'=>false,'result'=>'未找到账单'];
        }
        $item= $OrderClass->alias('o')
            ->join('order_item oi','o.id=oi.order_id','left')
            ->join('order_item_detail oid','oi.id=oid.order_item_id and oid.del_flag=0','left')
            ->join('product p','oi.pro_id = p.id or oid.pro_id=p.id','left')
            ->where('o.waybill_id','not null')
            ->where('o.id',$order_id)
            ->where('o.del_flag',0)
            ->where('o.pay_type','in',[4,6])
            ->where('o.order_status',1)
            ->where('oi.del_flag',0)
            ->field('o.id order_id,oi.id,oi.show_index,oi.pro_id,oi.cn_name,oi.en_name,oi.pur_price,oi.amount,oi.type,oi.selling_price,o.stock_status,oi.amount stock_out_amount,p.amount stock,oid.id detail_id,oid.pro_id detail_pro_id,oid.en_name detail_en_name,oid.cn_name detail_cn_name,oid.amount detail_amount,oid.pur_price detail_pur_price,oid.type detail_type,oi.remark,oid.remark detail_remark')
            ->order('oi.show_index')
            ->select()->toArray();
        if(empty($item)){
            return ['status'=>false,'result'=>'未找到符合条件的账单'];
        }
        if($item[0]['stock_status']===2){
            return ['status'=>false,'result'=>'已出库'];
        }
        $order_item=[];
        $order_item_index=[];
        $index=0;
        foreach ($item as $k=>$v){
            if ($v['type']==2){
                $stock_out_amount='';
            }else{
                $stock_out_amount=$v['stock_out_amount'];
            }
            if ($v['detail_type']==2){
                $detail_amount='';
            }else{
                $detail_amount=$v['detail_amount'];
            }
            if($v['pro_id']){
                //没有children
                $order_item_index[$v['id']]=$index;
                $order_item[$index]=['pur_price'=>$v['pur_price'],'amount'=>$v['amount'],'check'=>false,'children'=>[],'cn_name'=>$v['cn_name'],'en_name'=>$v['en_name'],'id'=>$v['id'],'order_id'=>$v['order_id'],'pro_id'=>$v['pro_id'],'selling_price'=>$v['selling_price'],'show_index'=>$v['show_index'],'stock'=>$v['stock'],'stock_out_amount'=>$stock_out_amount,'stock_status'=>$v['stock_status'],'type'=>$v['type'],'remark'=>$v['remark']];
                $index++;
            }else{
                if(!isset($order_item_index[$v['id']])||!$v['detail_id']){
                    $order_item_index[$v['id']]=$index;
                    $order_item[$index] = ['pur_price'=>$v['pur_price'],'amount'=>$v['amount'],'check'=>false,'cn_name'=>$v['cn_name'],'en_name'=>$v['en_name'],'id'=>$v['id'],'order_id'=>$v['order_id'],'pro_id'=>$v['pro_id'],'selling_price'=>$v['selling_price'],'show_index'=>$v['show_index'],'stock'=>0,'stock_out_amount'=>0,'stock_status'=>$v['stock_status'],'type'=>$v['type'], 'children' => []];
                    $index++;
                    if (!$v['detail_id']){
                        continue;
                    }
                }
                $order_item[$order_item_index[$v['id']]]['children'][] = ['pur_price'=>$v['detail_pur_price'],'amount'=>$v['detail_amount'],'check'=>false,'cn_name'=>$v['detail_cn_name'],'en_name'=>$v['detail_en_name'],'id'=>$v['id'].'-'.$v['detail_id'],'order_id'=>$v['order_id'],'pro_id'=>$v['detail_pro_id'],'selling_price'=>0,'show_index'=>$v['id'].'-'.$v['detail_id'],'stock'=>$v['stock'],'stock_out_amount'=>$detail_amount,'stock_status'=>$v['stock_status'],'type'=>$v['detail_type'],'remark'=>$v['detail_remark']];
            }
        }
        return ['status'=>true,'result'=>['items'=>$order_item,'order_id'=>$order_id]];
    }

    public static function getSalesAmount($search_param,$page_param,$sort_param): array
    {
        $OrderItemClass=new self();

        $where['oi.del_flag']=['=',0];
        $where['o.del_flag']=['=',0];
        $where['o.order_status']=['=',1];
        $where['oi.type']=['=',1];
        $where['oi.pro_id']=['<>',0];
        $where['o.pay_type']=['=',4];
        if (!empty($search_param['create_time'])) {
            $where['oi.create_time']=['between',[$search_param['create_time'][0].' 00:00:00',$search_param['create_time'][1].' 23:59:59']];
        }
        $obj=$OrderItemClass->alias('oi')
            ->join('__PRODUCT__ p','oi.pro_id=p.id','left')
            ->join('__ORDER__ o','oi.order_id=o.id','left')
            ->where($where)
            ->field('round(sum(oi.selling_price*'.usdExchange.')-sum(oi.amount*oi.pur_price),2) profit,round(sum(oi.amount),2) amount')
            ->select();
        if($obj->isEmpty()){
            $total_sales=[];
        }else{
            $total_sales=$obj->toArray();
        }

        $obj=$OrderItemClass
            ->where($where)->alias('oi')
            ->join('__PRODUCT__ p','oi.pro_id=p.id','left')
            ->join('__ORDER__ o','oi.order_id=o.id','left')
            ->field('p.cn_name,oi.pro_id,round(sum(oi.selling_price*'.usdExchange.')-sum(oi.amount*oi.pur_price),2) profit,round(sum(oi.amount),2) amount')
            ->group('oi.pro_id')
            ->order($sort_param['column'],$sort_param['desc'])
            ->paginate($page_param['page_size'],false,['page'=>$page_param['page_num']]);
        $count=$obj->total();
        $sales_data=$obj->items();

        return ['status'=>true,'result'=>['count'=>$count,'total_sales'=>$total_sales,'sales_data'=>$sales_data]];
    }

    public static function getOrderItemsByWaybill($waybill)
    {
        $waybillClass=new Waybill();
        $item=$waybillClass->alias('w')
            ->join('order o','w.id=o.waybill_id','left')
            ->join('order_item oi','o.id=oi.order_id','left')
            ->join('order_item_detail oid','oi.id=oid.order_item_id and oid.del_flag=0','left')
            ->join('product p','oi.pro_id = p.id or oid.pro_id=p.id','left')
            ->where(['w.ship_no'=>$waybill,'w.del_flag'=>0,'o.del_flag'=>0,'oi.del_flag'=>0])
            ->where('o.order_status',1)
            ->where('o.pay_type','in',[4,6])
            ->field('w.id waybill_id,o.id order_id,o.order_id orderId,oi.id,oi.show_index,oi.pro_id,oi.cn_name,oi.en_name,oi.pur_price,oi.amount,oi.type,oi.selling_price,o.stock_status,oi.amount stock_out_amount,p.amount stock,oid.id detail_id,oid.pro_id detail_pro_id,oid.en_name detail_en_name,oid.cn_name detail_cn_name,oid.amount detail_amount,oid.pur_price detail_pur_price,oid.type detail_type,oi.remark,oid.remark detail_remark')
            ->order('o.id,oi.show_index,oid.id')
            ->select()->toArray();
        if(empty($item)){
            return ['status'=>false,'result'=>'未找到符合条件的账单'];
        }
        if($item[0]['stock_status']===2){
            return ['status'=>false,'result'=>'已出库'];
        }
        $order_item=[];
        $order_item_index=[];
        $index=0;
        foreach ($item as $k=>$v){
            if ($v['type']==2){
                $stock_out_amount='';
            }else{
                $stock_out_amount=$v['stock_out_amount'];
            }
            if ($v['detail_type']==2){
                $detail_amount='';
            }else{
                $detail_amount=$v['detail_amount'];
            }
            if($v['pro_id']){
                //没有children
                $order_item_index[$v['id']]=$index;
                $order_item[$index]=['orderId'=>$v['orderId'],'pur_price'=>$v['pur_price'],'amount'=>$v['amount'],'check'=>false,'children'=>[],'cn_name'=>$v['cn_name'],'en_name'=>$v['en_name'],'id'=>$v['id'],'order_id'=>$v['order_id'],'pro_id'=>$v['pro_id'],'selling_price'=>$v['selling_price'],'show_index'=>$v['show_index'],'stock'=>$v['stock'],'stock_out_amount'=>$stock_out_amount,'stock_status'=>$v['stock_status'],'type'=>$v['type'],'remark'=>$v['remark']];
                $index++;
            }else{
                if(!isset($order_item_index[$v['id']])){
                    //不存在父集
                    $order_item_index[$v['id']]=$index;
                    $order_item[$index] = ['orderId'=>$v['orderId'],'pur_price'=>$v['pur_price'],'amount'=>$v['amount'],'check'=>false,'cn_name'=>$v['cn_name'],'en_name'=>$v['en_name'],'id'=>$v['id'],'order_id'=>$v['order_id'],'pro_id'=>$v['pro_id'],'selling_price'=>$v['selling_price'],'show_index'=>$v['show_index'],'stock'=>$v['stock'],'stock_out_amount'=>$stock_out_amount,'stock_status'=>$v['stock_status'],'type'=>$v['type'],'remark'=>$v['remark'], 'children' => []];
                    $index++;
                    if (!$v['detail_id']){
                        continue;
                    }
                }
                $order_item[$order_item_index[$v['id']]]['children'][]=['orderId'=>$v['orderId'],'pur_price'=>$v['detail_pur_price'],'amount'=>$v['detail_amount'],'check'=>false,'cn_name'=>$v['detail_cn_name'],'en_name'=>$v['detail_en_name'],'id'=>$v['id'].'-'.$v['detail_id'],'order_id'=>$v['order_id'],'pro_id'=>$v['detail_pro_id'],'show_index'=>$v['id'].'-'.$v['detail_id'],'stock'=>$v['stock'],'stock_out_amount'=>$detail_amount,'stock_status'=>$v['stock_status'],'type'=>$v['detail_type'],'remark'=>$v['detail_remark']];
            }
        }

        return ['status'=>true,'result'=>['items'=>$order_item,'waybill_id'=>$item[0]['waybill_id']]];
    }
    public static function changeGoods($data)
    {
        $productClass=new Product();
        $orderItemDetailClass=new OrderItemDetail();
        $orderClass=new Order();
        $orderItemClass=new self();
        $pro_ids=[];
        foreach($data['product'] as $k=>$v){
            if(!$v['pro_id']){
                return ['code'=>1,'输入商品错误'=>$v['en_name']];
            }
            $pro_ids[] = $v['pro_id'];
        }
        $orderItemClass->startTrans();
        try {
            $orderItem=$orderItemClass->where('id',$data['order_item_id'])->field('pro_id,amount,demand_stock,lock_quantity,order_id,type')->find();
            if($orderItem['pro_id']!==0 && $orderItem['type']===1) {
                $product = $productClass->where('id', $orderItem['pro_id'])->lock(true)->field('demand_stock,locked_demand_stock,locked_quantity')->find();
                $amount = $product['demand_stock'] - $orderItem['amount'];
                $locked_demand_stock = $product['locked_demand_stock'] - $orderItem['demand_stock'];
                $locked_quantity = $product['locked_quantity'] - $orderItem['lock_quantity'];
                $result = $productClass->where('id', $orderItem['pro_id'])->update(['demand_stock' => $amount, 'locked_demand_stock' => $locked_demand_stock, 'locked_quantity' => $locked_quantity]);
                if ($result === false) {
                    return ['status' => false, 'result' => '更改库存信息失败'];
                }
            }
            $stock_list = $productClass->where('id', 'in', $pro_ids)->where('del_flag', 0)->lock(true)->column('amount,type,demand_stock,locked_demand_stock,type,locked_quantity,en_name,cn_name,pur_price', 'id');

            $detail_data=[];
            $product_data=[];
            $bool=true;

            foreach($data['product'] as $k=>$v){
                $arr =& $stock_list[$v['pro_id']];
                $detail_data[$k]['order_item_id']=$data['order_item_id'];
                $detail_data[$k]['pro_id']=$v['pro_id'];
                $detail_data[$k]['en_name']=$arr['en_name'];
                $detail_data[$k]['cn_name']=$arr['cn_name'];
                $detail_data[$k]['remark']=$v['remark'];
                $detail_data[$k]['pur_price']=$arr['pur_price'];
                $detail_data[$k]['type']=$arr['type'];
                if ($arr['type']==1){
                    $detail_data[$k]['weight']='';
                    $detail_data[$k]['amount']=$v['amount'];
                    $items=[
                        'type'=>1,
                        'amount'=>$v['amount'],
                        'demand_stock'=>0,
                        'lock_quantity'=>0,
                    ];

                    ['demand_stock' => $demand_stock, 'locked_stock' => $locked_stock,'stock_demand_stock'=>$stock_demand_stock, 'stock_locked_stock' => $stock_locked_stock,'stock_locked_demand_stock'=>$stock_locked_demand_stock] = Common::lockedStock($arr, $items);
                    $detail_data[$k]['demand_stock'] = $demand_stock;
                    $detail_data[$k]['lock_quantity'] = $locked_stock;
                    if ($v['amount']==$locked_stock){
                        $detail_data[$k]['lock_status'] = 1;
                    }else{
                        $detail_data[$k]['lock_status'] = 0;
                        $bool=false;
                    }
                    $arr['demand_stock']=$stock_demand_stock;
                    $arr['locked_demand_stock']=$stock_locked_demand_stock;
                    $arr['locked_quantity']=$stock_locked_stock;
                }else{
                    $detail_data[$k]['amount']=$v['amount'];
                    $detail_data[$k]['demand_stock'] = 0;
                    $detail_data[$k]['lock_quantity'] = 0;
                    $detail_data[$k]['lock_status'] = 1;
                }
            }
            $result=$orderItemDetailClass->isUpdate(false)->saveAll($detail_data);
            if ($result===false){
                return ['status'=>false,'result'=>'商品添加失败'];
            }
            $result=$productClass->isUpdate(true)->allowField(['id,demand_stock,locked_demand_stock,locked_quantity'])->saveAll($stock_list);
            if ($result===false){
                return ['status'=>false,'result'=>'库存更新失败'];
            }
            if ($bool){
                $orderItem_update=['pro_id'=>0,'demand_stock'=>0,'lock_quantity'=>0,'lock_status'=>1];
            }else{
                $orderItem_update=['pro_id'=>0,'demand_stock'=>0,'lock_quantity'=>0,'lock_status'=>0];
            }
            $result=$orderItemClass->where('id',$data['order_item_id'])->update($orderItem_update);
            if (!$result){
                return ['status'=>false,'result'=>'订单数量清除失败'];
            }
            $lock_status=$orderItemClass->where(['order_id'=>$orderItem['order_id'],'del_flag'=>0,'lock_status'=>0])->select();

            if ($lock_status->isEmpty()){
                $orderClass->where('id',$orderItem['order_id'])->update(['logistics_status'=>1,'stock_status'=>1]);
            }else{
                $orderClass->where('id',$orderItem['order_id'])->update(['logistics_status'=>0,'stock_status'=>1]);
            }
            $orderItemClass->commit();
            return ['status'=>true,'result'=>['msg'=>'创建成功','pro_id'=>$orderItem['pro_id']]];
        }catch (\Exception $e) {
            $orderItemClass->rollback();
            trace($e->getMessage(),'error');
            return ['status'=>false,'result'=>'创建失败'.$e->getMessage()];
        }
    }

    /**
     * 获取需求库存详情列表
     * create by yhb on 2021/3/29 10:21
     * @param array $data
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getProductStockList($id)
    {
        $orderItem = new self();
        $customerOrderClass=new CustomerOrder();
        $where=[];
        $where['co.status']=['=',0];
        $where['co.del_flag']=['=',0];
        $where['c.del_flag']=['=',0];
        $customer_order_sql = $customerOrderClass
            ->alias('co')
            ->join('customer_order_detail cod','co.id = cod.customer_order_id and cod.del_flag = 0','left')
            ->join('customer c','co.customer_name = c.id','left')
            ->where(function ($query)use($id){
                $query->where('co.pro_id',$id)->whereOr('cod.pro_id',$id);
            })
            ->where($where)
            ->field('0 total_amount,0 pay_amount,sum(if(co.pro_id != 0, co.amount, 0)) + IFNULL(sum(cod.amount), 0) unorder_amount,co.customer_name customer_id,c.customer_name')
            ->group('customer_id')
            ->buildSql();


        $where = [];
        $where['o.logistics_status'] = ['in',[0,1]];
        $where['o.stock_status'] = ['in',[1]];
        $where['o.order_status'] = ['=',1];
        $where['o.del_flag'] = ['=',0];
        $where['c.del_flag'] = ['=',0];
        $order_item_sql = $orderItem
            ->alias('oi')
            ->join('order o','o.id = oi.order_id and oi.del_flag=0','left')
            ->join('order_item_detail oid','oi.id = oid.order_item_id and oid.del_flag=0','left')
            ->join('customer c','c.id = o.customer_id','left')
            ->where(function ($query)use($id){
                $query->where('oi.pro_id',$id)->whereOr('oid.pro_id',$id);
            })
            ->where($where)
            ->field('sum(if(oi.pro_id != 0, oi.amount, 0)) + IFNULL(sum(oid.amount), 0) total_amount,sum(if(o.pay_type = 4 and oi.pro_id != 0, oi.amount, 0)) +IFNULL(sum(if(o.pay_type = 4, oid.amount, 0)), 0) pay_amount,0 unorder_amount,o.customer_id,c.customer_name')
            ->group('o.customer_id')
            ->union($customer_order_sql)
            ->buildSql();
        $data=Db::query('select total_amount,pay_amount,(total_amount-pay_amount) unpaid_amount,unorder_amount,customer_id,customer_name from '.$order_item_sql.' a group by a.customer_id');
        if(!empty($data)){
            $productStock=$data;
        }else{
            $productStock=[];
        }
        return ['status'=>true,'result'=>['data'=>$productStock]];

    }

    public static function distributionStock($id,$ids)
    {
        $orderItemClass=new self();
        $orderClass=new Order();
        $OrderHistoryClass=new OrderHistory();
        $orderItemList=$orderItemClass->alias('oi')
            ->join('order o','o.id=oi.order_id')
            ->where('oi.id','in',$ids)
            ->order('o.payment_time desc')
            ->field('oi.id,oi.amount,oi.lock_quantity,o.id order_id')->select();
        $order_id=$orderItemClass->where('id',$id)->field('order_id,amount,lock_quantity')->find();
        $lock_quantity=$order_id['amount'];
        $number=$order_id['amount']-$order_id['lock_quantity'];
        $data=[];
        $update_order=[];
        $insert_history=[];
        $user=session('Login_user')['id'];
        foreach ($orderItemList as $k=>$v){
            if ($number==0){
                continue;
            }
            if ($v['lock_quantity']<=$number){
                $data[$k]['id']=$v['id'];
                $data[$k]['lock_quantity']=0;
                $number=$number-$v['lock_quantity'];
            }else{
                $data[$k]['id']=$v['id'];
                $data[$k]['lock_quantity']=$v['lock_quantity']-$number;
                $number=0;
            }
            $insert_history[$k]['order_id']=$v['order_id'];
            $insert_history[$k]['operational']='被分配库存';
            $insert_history[$k]['operator']=$user;
            if ($v['amount']>$data[$k]['lock_quantity']){
                $data[$k]['lock_status']=0;
                $update_order[$k]['id']=$v['order_id'];
                $update_order[$k]['logistics_status']=0;
            }else{
                $data[$k]['lock_status']=1;
            }
        }
        $insert_data=[
            'order_id'=>$order_id['order_id'],
            'operational'=>'分配库存',
            'operator'=>$user,
        ];
        $orderItemClass->startTrans();
        try {
            $result=$orderItemClass->isUpdate(true)->saveAll($data);
            if (!$result){
                return ['status'=>false,'result'=>'操作失败'];
            }
            $result=$orderItemClass->where('id',$id)->update(['lock_quantity'=>$lock_quantity,'lock_status'=>1]);
            if ($result===false){
                return ['status'=>false,'result'=>'操作失败'];
            }
            $result=$orderClass->isUpdate(true)->saveAll($update_order);
            if (!$result){
                return ['status'=>false,'result'=>'操作失败'];
            }
            $lock_status=$orderItemClass->where(['order_id'=>$order_id['order_id'],'del_flag'=>0])->column('lock_status');
            $bool=true;
            foreach ($lock_status as $v){
                if ($v==0){
                    $bool=false;
                }
            }
           if ($bool){
               $result=$orderClass->where('id',$order_id['order_id'])->update(['logistics_status'=>1]);
               if ($result===false){
                   return ['status'=>false,'result'=>'操作失败'];
               }
           }else{
               $result=$orderClass->where('id',$order_id['order_id'])->update(['logistics_status'=>0]);
               if ($result===false){
                   return ['status'=>false,'result'=>'操作失败'];
               }
           }

            $result=$OrderHistoryClass->isUpdate(false)->saveAll($insert_history);
            if($result===false){
                return ['status'=>false,'result'=>'历史记录失败'];
            }
            $result=$OrderHistoryClass->save($insert_data);
            if($result===false){
                return ['status'=>false,'result'=>'历史记录失败'];
            }
            $orderItemClass->commit();
            return ['status'=>true,'result'=>'分配库存成功'];
        }catch (\Exception $e) {
            $orderItemClass->rollback();
            trace($e->getMessage(),'error');
            return ['status'=>false,'result'=>'操作失败'.$e->getMessage()];
        }
    }
}